﻿// Shader-Based-Image-Processing (SBIP)
// http://code.google.com/p/sbip/
//
// Copyright © Frank Nagl, 2009-2011
// admin@franknagl.de
//
namespace SBIP.Helper
{
    using System.Drawing;
    using SBIP.Helper.ColorSpace;

    /// <summary>
    /// Container for RGB pixel's 2d .Net image coordinates and its color.
    /// </summary>
    public class PixelLUV
    {
        private ColorTriple color;
        private Point point;

        #region properties

        /// <summary>LUV channels as <see cref="ColorTriple"/>.</summary>
        public ColorTriple Color
        {
            get { return color; }
            set { color = value; }
        }

        /// <summary>L channel of pixel's color.</summary>
        public float L
        {
            get { return color.A; }
            set { color.A = value; }
        }

        /// <summary>U channel of pixel's color.</summary>
        public float U
        {
            get { return color.B; }
            set { color.C = value; }
        }

        /// <summary>X- and Y-coordinate as <see cref="Point"/>.</summary>
        public Point Point
        {
            get { return point; }
            set { point = value; }
        }

        /// <summary>V channel of pixel's color.</summary>
        public float V
        {
            get { return color.C; }
            set { color.C = value; }
        }

        /// <summary>Reserved color value, with no direct function, can be used for 
        /// additional information.</summary>
        public Color Reserved { get; set; }

        /// <summary>Reserved integer value, with no direct function, can be used for 
        /// additional information like an identifier.</summary>
        public int ReservedId { get; set; }

        /// <summary>X-coordinate.</summary>
        public int X  
        {
            get { return point.X; }
            set { point.X = value; }
        }

        /// <summary>Y-coordinate.</summary>
        public int Y
        {
            get { return point.Y; }
            set { point.Y = value; }
        }

        #endregion properties

        /// <summary>
        /// Determines whether the <paramref name="externalColor"/> is same color.
        /// Alpha channel is irrelevant for evaluating.
        /// </summary>
        /// <param name="externalColor">The color to compare.</param>
        /// <param name="colorThreshold">The color threshold for allowed 
        /// variation between the own color and 
        /// <paramref name="externalColor"/>.</param>
        /// <returns>
        ///   <c>True</c> if it is the same color; otherwise, <c>false</c>.
        /// </returns>
        public bool IsSameColor(ColorTriple externalColor, float colorThreshold)
        {
            return Vector.Distance(Color, externalColor) <= colorThreshold;
        }

        /// <summary>
        /// Implements the operator +.
        /// </summary>
        /// <param name="pixel">The original <see cref="PixelRGBA"/>.</param>
        /// <param name="size">The size to move the coordinates.</param>
        /// <returns>The resulting <see cref="PixelRGBA"/> with new coordinates.
        /// </returns>
        public static PixelLUV operator +(PixelLUV pixel, Size size)
        {
            return new PixelLUV
                       {
                           L = pixel.L,
                           U = pixel.U,
                           V = pixel.V,
                           Reserved = pixel.Reserved,
                           ReservedId = pixel.ReservedId,
                           X = pixel.X + size.Width,
                           Y = pixel.Y + size.Height
                       };
        }

        /// <summary>
        /// Implements the operator -.
        /// </summary>
        /// <param name="pixel">The original <see cref="PixelRGBA"/>.</param>
        /// <param name="size">The size to move the coordinates.</param>
        /// <returns>The resulting <see cref="PixelRGBA"/> with new coordinates.
        /// </returns>
        public static PixelLUV operator -(PixelLUV pixel, Size size)
        {
            return new PixelLUV
                       {
                           L = pixel.L,
                           U = pixel.U,
                           V = pixel.V,                           
                           Reserved = pixel.Reserved,
                           ReservedId = pixel.ReservedId,
                           X = pixel.X - size.Width,
                           Y = pixel.Y - size.Height
                       };
        }
    }
}
